package com.etlmaster.executor.steps.loop;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import com.etlmaster.executor.utils.Regex;
import com.etlmaster.executor.utils.StepState;

/**
 * @author Wugf
 * @date 2016-03-08
 */
public class DefaultLoopProcessor extends LoopProcessor {

	@Override
	public int process() throws InterruptedException, ExecutionException {
		String[] arr = expression.split(";");
		ScriptEngineManager sem = new ScriptEngineManager();
		ScriptEngine engine = null;
		try {
			engine = sem.getEngineByName("nashorn");
			if (engine == null) {
				loopStepMeta.log("DEBUG", "创建nashorn引擎失败，未使用Jdk 8，使用默认Rhino引擎");
				engine = sem.getEngineByName("JavaScript");
			}
		} catch (Exception e) {
			loopStepMeta.log("DEBUG", "创建nashorn引擎失败，不是使用Jdk 8使用默认Rhino引擎，{}",
					e.getMessage());
			engine = sem.getEngineByName("JavaScript");
		}

		Compilable compilable = (Compilable) engine;
		try {
			CompiledScript jsFunc1 = compilable.compile(arr[0]);
			StringBuilder script = new StringBuilder("(function(){return ");
			script.append(arr[1]).append(" ;})()");
			CompiledScript jsFunc2 = compilable.compile(script.toString());
			Bindings bindings = engine.createBindings();
			for (Iterator iterator = job.getVariables().entrySet().iterator(); iterator
					.hasNext();) {
				Map.Entry<String, Object> entry = (Map.Entry<String, Object>) iterator
						.next();
				bindings.put(entry.getKey(), entry.getValue());
			}
			StringBuilder script2 = new StringBuilder("(function(){return ");
			script2.append(arr[2]).append(" ;})()");
			CompiledScript jsFunc3 = compilable.compile(script2.toString());
			jsFunc1.eval(bindings);
			String paraName = Regex.validation(arr[0], "(var|)\\s*(.*)=.*", 2);
			//String totalNum= Regex.validation(arr[1].replace("=", ""), ".*(<|>)(.*)", 2);
			
			for (; (Boolean) jsFunc2.eval(bindings);) {

				//job.getVariables().put(paraName, i);
				i++;
				bindings.put(paraName, i);

						
				Boolean isBreak = (Boolean) job.getVariable("isBreak");
				if ((isBreak != null && (Boolean) job.getVariable("isBreak"))
						|| loopStep instanceof EndLoopStep) {
					break;
				}
				loopStepMeta.runLoop(job,i-1,paraName);
				
			}
			loopStepMeta.startLoopStack();
			
		} catch (ScriptException e) {
			loopStepMeta.log("ERROR", "循环表达式失败，{}", e.getMessage());
			return StepState.RUNNING_FAILED;

		} 
		return StepState.RUNNING_SUCCESSED;
	}

}
